//////////////////////////////////////////////////////////////////////////////
//																			//
//  Filename:    AchillesGuts.h												//
//  Developer:   Ben Wardlow												//
//  Create date: 5/15/2006													//
//																			//
//////////////////////////////////////////////////////////////////////////////
//																			//
//  Description: This is the class declaration for the slot gut of the		//
//               Australian Slot machine called Achilles.					//
//																			//
//////////////////////////////////////////////////////////////////////////////
//        Copyright (c) 2006 - Realtime Gaming.  All rights reserved.		//
//////////////////////////////////////////////////////////////////////////////

#ifndef __ACHILLES_GUTS_H__
#define __ACHILLES_GUTS_H__

#pragma once

//#define DEBUG_KNOWNSPINS
#ifdef DEBUG_KNOWNSPINS
#pragma message("This is a DEBUG_KNOWNSPINS compilation!")
#endif

#include "slotguts.h"
#include "getrand.h"

class AchillesGuts :
	public SlotGuts
{
	typedef SlotGuts super;

public:
	enum GutsRange
	{
		MIN = 3200,
		MAX = 3299
	};


private:

	#include "AchillesCommon.h"

	// Helpful lookup arrays.
	static SpinResult m_aLineWinSpinResults[][6];
	static SpinResult m_aScatterWinSpinResults[6];

	// Inline functions that also do bounds checking to use with the arrays.
	static SpinResult lookupLineWinSpinResult( uint8 nIconType, uint8 nCount )
	{
		if ( nIconType < NUM_VALID_ICONS && nCount < 6 )
		{
			return m_aLineWinSpinResults[ nIconType ][ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	static SpinResult lookupScatterWinSpinResult( uint8 nCount )
	{
		if ( nCount < 6 )
		{
			return m_aScatterWinSpinResults[ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

public:

	AchillesGuts(void);
	virtual ~AchillesGuts(void);
	virtual void classifyStops( SpinLine* spinLine, uint8* stops, uint8 bet, uint8 line,
		uint8& rtnResult, uint8& multiplier );
	virtual void classifyScatters( SlotSpin* spin );
	virtual bool8 isValidGuts();
	virtual void getGameModeMultiplierAndNoteId (uint8& nGameModeMultiplier, uint8& nNoteId );
	virtual bool8 processClientData( uint8 bonusGameType, int32 bonusDataCount, int32 *bonusData );
	virtual bool8 hasSavedGames();
	virtual void postSpinClassifyResults( SlotSpin* spin );

protected:

	// Helper functions for classifyStops.
	SpinResult getAchillesLineWinResult( uint8* stops ) const;
	bool doesAchillesLineWinPayMore( SpinResult srAchilles, SpinResult srOther ) const;
	SpinResult getLineWinResultWithPossibleSubstitution( uint8* stops, uint8 testIcon, bool& bSubstitution, uint8& numLineWinIcons ) const;

	// Helper functions for classifyScatters.
	void tryForJackpot( SlotSpin* spin );
	SpinResult getScatterWinResult( SlotSpin* spin, int32& scatterPositions ) const;
	void evaluateScatterWin( SlotSpin* spin, SpinResult srScatterResult, int32 scatterPositions );
	void evaluateFeatureTrigger( SlotSpin* spin, SpinResult srFeatureTriggerResult, int32 featurePositions );
	uint8 getNumFeatureTriggerIcons( SlotSpin* spin, uint8 icon, int32& scatterPositions ) const;
	virtual void setSelectAchillesIcon( int32 bSelectAchillesIcon );
	virtual int32 getSelectAchillesIcon() const;
	void setAchillesIconMask( int32 scatterPositions );

	virtual void Debug_SetLoserStops( uint8* pStops );

#ifdef DEBUG_KNOWNSPINS

	static int g_nSpinNum;
	static uint8 g_aDebugStops[][5];
	static uint8 g_aCustomDebugStops[][5];

	// Custom debug stop procedure prototype.
	typedef	void (AchillesGuts::*DEBUG_STOP_PROC)( uint8* pStops );

	static DEBUG_STOP_PROC g_FunctionTable[];

	static SpinResult g_aDataSet1[];
	static SpinResult g_aDataSet2[];
	static SpinResult g_aDataSet3[];
	static SpinResult g_aDataSet4[];
	static SpinResult g_aDataSet5[];

	static SpinResult* g_aAllDataSets[];

	static int g_nCurrentDataSet;

    static bool m_bForceRandomJackpot;

	// Helper function
	void CopyDebugStops( SpinResult sr, uint8* pStops );

	// Custom debug stop generator functions.
	void DebugStops_ReelConfig( uint8* pStops );
	void DebugStops_FeatureExit( uint8* pStops );
	void DebugStops_ScatterIterate( uint8* pStops );
	void DebugStops_PayLineIterate( uint8* pStops );
	void DebugStops_RandomJackpot( uint8* pStops );
    void DebugStops_RandomJackpotNext( uint8* pStops );
    void DebugStops_FeatureExitWin( uint8* pStops );

    void DebugStops_SubstituteAchilles1( uint8* pStops );
    void DebugStops_SubstituteAchilles2( uint8* pStops );
    void DebugStops_SubstituteAchilles3( uint8* pStops );
    void DebugStops_SubstituteAchilles4( uint8* pStops );
    void DebugStops_SubstituteAchilles5( uint8* pStops );
    void DebugStops_SubstituteTroy1( uint8* pStops );
    void DebugStops_SubstituteTroy2( uint8* pStops );
    void DebugStops_SubstituteTroy3( uint8* pStops );
    void DebugStops_SubstituteTroy4( uint8* pStops );
    void DebugStops_SubstituteTroy5( uint8* pStops );

	void processDebugStops( SlotSpin *spin );

	// Override of the framework function.
	virtual void preSpinClassifyResults( SlotSpin *spin );
#endif

};

#endif //__ACHILLES_GUTS_H__
